package ar.com.seminario.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import ar.com.seminario.common.persistence.exception.DaoException;
import ar.com.seminario.common.service.definition.BaseService;
import ar.com.seminario.common.service.exception.ServiceException;
import ar.com.seminario.dao.PerfilDao;
import ar.com.seminario.dto.DetallePerfilDto;
import ar.com.seminario.dto.PerfilDto;
import ar.com.seminario.model.DetallePerfil;
import ar.com.seminario.model.Perfil;

/**
 * Servicio de acceso a los perfiles.
 * 
 * @author Pablo Lamas
 * 
 */
@Service
@Transactional
public class PerfilService extends BaseService implements IPerfilService {

	public PerfilDto getPerfilDto(Perfil perfil) {

		return toPerfilDto(perfil);
	}

	public List<PerfilDto> getAllPerfilesDto() throws ServiceException {

		List<PerfilDto> perfiles = new ArrayList<PerfilDto>();

		try {

			PerfilDao dao = this.getDaoFactory().newDao(PerfilDao.class);
			for (Perfil perfil : dao.getAll(Perfil.class)) {

				perfiles.add(toPerfilDto(perfil));
			}

		} catch (final DaoException e) {
			throw new ServiceException(e);
		}

		return perfiles;
	}

	/**
	 * Carga los detalles del perfil.
	 */
	private List<DetallePerfilDto> getDetallesPerfilDto(
			List<DetallePerfil> detalles) {

		List<DetallePerfilDto> detallesDto = new ArrayList<DetallePerfilDto>();
		if (detalles != null) {
			for (DetallePerfil detallePerfil : detalles) {
				DetallePerfilDto detallePerfilDto = new DetallePerfilDto();
				detallePerfilDto.setDescripcion(detallePerfil.getDescripcion());
				detallePerfilDto.setEsObligatorio(detallePerfil
						.getEsObligatorio());
				detallePerfilDto.setGrupoPerfilId(detallePerfil
						.getGrupoPerfil().getId());
				detallePerfilDto.setPonderacion(detallePerfil.getPonderacion());
				detallePerfilDto.setValor(detallePerfil.getValor());
				detallesDto.add(detallePerfilDto);
			}
		}

		return detallesDto;
	}

	private PerfilDto toPerfilDto(Perfil perfil) {
		PerfilDto perfilDto = new PerfilDto();
		perfilDto.setId(perfil.getId());
		perfilDto.setDetalles(this.getDetallesPerfilDto(perfil
				.getAllDetallesPerfil()));
		perfilDto.setNombre(perfil.getNombre());
		perfilDto.setDescripcion(perfil.getDescripcion());
		perfilDto.setEsTemplate(perfil.getEsTemplate());
		return perfilDto;
	}

	/**
	 * Busco los perfiles que cumplan con el pasado por parametro
	 */
	public List<PerfilDto> getPerfilesCompatibles(Perfil perfil) {

		List<PerfilDto> perfilesCompatibles = new Vector<PerfilDto>();
		PerfilDao dao;
		try {
			dao = this.getDaoFactory().newDao(PerfilDao.class);
			DetallePerfilDto detalleEvaluado = null;
			PerfilDto perfilDto = null;
			for (Perfil perfilEvaluado : dao.getAll(Perfil.class)) {
				perfilDto = toPerfilDto(perfilEvaluado);
				if (!perfilEvaluado.getEsTemplate() && 
							tieneDetallesObligatorios(perfil, perfilEvaluado)) {
					for (DetallePerfil detalle : perfil.getAllDetallesPerfil()) {

						detalleEvaluado = perfilDto.getDetalle(detalle);
						if (detalleEvaluado != null) {
							detalleEvaluado.setEvaluacion(detalleEvaluado
									.getValor()
									* detalle.getPonderacion().getValor());
						}

					}
					perfilesCompatibles.add(perfilDto);
				}
				
					
				
			}
		} catch (DaoException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Collections.sort(perfilesCompatibles);
		
		return perfilesCompatibles;
	}

	private boolean tieneDetallesObligatorios(Perfil perfil,
			Perfil perfilEvaluado) {
		return perfilEvaluado.tieneTodosDetalles(perfil
				.getDetallesObligatorios());

	}

	public Perfil getPerfilById(Long idPerfil) throws ServiceException {

		if (idPerfil == null) {
			throw new ServiceException(
					"El campo idPerfil es requerido para obtener un Perfil");
		}

		try {

			PerfilDao dao = this.getDaoFactory().newDao(PerfilDao.class);
			return dao.getPerfilPorId(idPerfil);

		} catch (DaoException e) {
			throw new ServiceException("Error obteniendo el perfil", e);
		}
	}

}